/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package desarrollosoft.ghce.vista.implementaciones;

import desarrollosoft.ghce.entidades.EstudioImaginologia;
import desarrollosoft.ghce.entidades.Gravedad;
import desarrollosoft.ghce.entidades.Imagen;
import desarrollosoft.ghce.entidades.Paciente;
import desarrollosoft.ghce.entidades.Profesional;
import desarrollosoft.ghce.servicio.interfaces.IServicioHistorial;
import desarrollosoft.ghce.soporte.SecurityUtil;
import desarrollosoft.ghce.vista.interfaces.Actualizable;
import desarrollosoft.ghce.vista.interfaces.Avisable;
import desarrollosoft.ghce.vista.interfaces.Estado;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.zkoss.bind.BindContext;
import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.Init;
import org.zkoss.util.media.Media;
import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.Filedownload;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Window;

/**
 *
 * @author ariel
 */
@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class ControladoraVentanaCargaResultadoImaginologia implements Avisable {

    @WireVariable("servicioHistorial")
    private IServicioHistorial servicioHistorial;

    private EstudioImaginologia estudioImaginologia;
    private EstudioImaginologia estudioImaginologiaAnterior;
    private Paciente paciente;
    private Actualizable actualizable;
    private Estado estado;
    private String nombreUsuarioActual;

    private List<Imagen> listaImagenes;
    private String nombreEstudio;
    private List<Gravedad> listaGravedades;

    private Imagen imagenSeleccionada;

    private boolean botonesActivados;

    @Init
    public void inicializar() {
        Execution ejecucion = Executions.getCurrent();
        estudioImaginologia = (EstudioImaginologia) ejecucion.getArg().get("estudioImaginologia");
        paciente = (Paciente) ejecucion.getArg().get("paciente");
        actualizable = (Actualizable) ejecucion.getArg().get("actualizable");
        estado = (Estado) ejecucion.getArg().get("estado");
        nombreUsuarioActual = SecurityUtil.getUserName();

        nombreEstudio = "Nombre Estudio: " + estudioImaginologia.getPlantillaEstudioImagenes().getNombre();
        listaGravedades = servicioHistorial.obtenerTodasGravedades();

        if (estado.equals(Estado.CONSULTANDO)) {
            listaImagenes = estudioImaginologia.getListaImagenes();
            botonesActivados = false;
        } else if (estado.equals(Estado.MODIFICANDO)) {
            estudioImaginologiaAnterior = estudioImaginologia.clonar();
            listaImagenes = estudioImaginologia.getListaImagenes();
            if (listaImagenes == null) { // solo si es null, le invento una lista vacia
                listaImagenes = new ArrayList<>();
                estudioImaginologia.setListaImagenes(listaImagenes);
            }
            botonesActivados = true;
        }
    }

    @Command("verQuienCompleto")
    public void clickBotonVerQuienCompleto() {
        Profesional profesionalQueCompleto = estudioImaginologia.getProfesionalQueLoCompleto();
        if (profesionalQueCompleto == null) {
            Messagebox.show("Este estudio todavía no ha sido completado");
            return;
        }
        Map<String, Object> argumentos = new HashMap<>();
        argumentos.put("profesional", profesionalQueCompleto);
        Window ventana = (Window) Executions.createComponents("VentanaDetallesProfesional.zul", null, argumentos);
        ventana.doModal();
    }

    @Command("verImagen")
    public void clickBotonVerImagenSeleccionada() {
        if (imagenSeleccionada == null) {
            Messagebox.show("Debe seleccionar una imagen de la lista para verla");
            return;
        }
        Map<String, Object> argumentos = new HashMap<>();
        argumentos.put("imagen", imagenSeleccionada);
        argumentos.put("estado", Estado.CONSULTANDO);
        argumentos.put("avisable", this);
        Window ventana = (Window) Executions.createComponents("VentanaCargaConsultaImagen.zul", null, argumentos);
        ventana.doModal();
    }

    @Command("modificarImagen")
    public void clickModificarImagen() {
        if (imagenSeleccionada == null) {
            Messagebox.show("Debe seleccionar una imagen de la lista para modificarla");
            return;
        }
        Map<String, Object> argumentos = new HashMap<>();
        argumentos.put("imagen", imagenSeleccionada);
        argumentos.put("estado", Estado.MODIFICANDO);
        argumentos.put("avisable", this);
        Window ventana = (Window) Executions.createComponents("VentanaCargaConsultaImagen.zul", null, argumentos);
        ventana.doModal();
    }

    @Command("cargarImagen")
    public void clickCargarImagen() {
        Map<String, Object> argumentos = new HashMap<>();
        argumentos.put("estado", Estado.CREANDO);
        argumentos.put("listaImagenes", listaImagenes);
        argumentos.put("avisable", this);
        Window ventana = (Window) Executions.createComponents("VentanaCargaConsultaImagen.zul", null, argumentos);
        ventana.doModal();
    }

    @Command("subirArchivoInforme")
    public void clickBotonSubirArchivoInforme(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {
        UploadEvent eventoSubida = null;
        Object eventoSubidaObject = ctx.getTriggerEvent();
        if (eventoSubidaObject != null && (eventoSubidaObject instanceof UploadEvent)) {
            eventoSubida = (UploadEvent) eventoSubidaObject;
        }
        if (eventoSubida == null) {
            Messagebox.show("Error al subir el archivo, intente nuevamente", "Error", Messagebox.OK, Messagebox.ERROR);
            return;
        }
        Media media = eventoSubida.getMedia();
        
        if (!media.getFormat().equals("pdf")) {
            Messagebox.show("Asegurese de subir un archivo con extensión \".pdf\"");
            return;
        }
        
        /* guarda derecho, no se fija en la extension ni nada */
        estudioImaginologia.setArchivoInforme(media.getByteData());
        estudioImaginologia.setNombreArchivo(media.getName());
        BindUtils.postNotifyChange(null, null, this, "*");
    }

    @Command("descargarArchivoInforme")
    public void clickBotonDescargarArchivoInforme() {
        byte bytesArchivo[] = estudioImaginologia.getArchivoInforme();
        if (bytesArchivo == null) {
            Messagebox.show("No se ha subido archivo de informe para este estudio");
            return;
        }
        File archivoTemporal;
        try {
            String directorioTemporal = System.getProperty("java.io.tmpdir");
            archivoTemporal = new File(directorioTemporal, estudioImaginologia.getNombreArchivo());
            FileOutputStream fileOuputStream = new FileOutputStream(archivoTemporal); 
	    fileOuputStream.write(bytesArchivo);
	    fileOuputStream.close();
        } catch (IOException ex) {
            Messagebox.show("Error al crear archivo temporal, intente nuevamente");
            return;
        }
        try {
            /* 2° argumento en null, para que determine solo el tipo de archivo */
            Filedownload.save(archivoTemporal, null);
        } catch (FileNotFoundException ex) {
            Messagebox.show("Error al descargar el archivo, intente nuevamente");
        }
    }

    @Command("guardar")
    public void clickBotonGuardar() {
        try {
            servicioHistorial.modificarEstudioImaginologia(estudioImaginologia, listaImagenes, nombreUsuarioActual);
            actualizable.guardaronVentanaHija(new Object());
        } catch (Exception ex) {
            Messagebox.show(ex.toString());
        }
    }

    @Command("cancelar")
    public void clickBotonCancelar() {
        if (estado.equals(Estado.CREANDO)) { // creando no es posible como estado
            estudioImaginologia = new EstudioImaginologia();
            botonesActivados = false;
            actualizable.cancelaron();
        } else {
            setearParametros(estudioImaginologia, estudioImaginologiaAnterior);
            botonesActivados = false;
        }
        BindUtils.postNotifyChange(null, null, this, "*");
    }

    private void setearParametros(EstudioImaginologia actual, EstudioImaginologia anterior) {
        actual.setArchivoInforme(anterior.getArchivoInforme());
        actual.setFecha(anterior.getFecha());
        actual.setFechaFin(anterior.getFechaFin());
        actual.setGravedad(anterior.getGravedad());
        actual.setId(anterior.getId());
        actual.setInforme(anterior.getInforme());
        actual.setListaImagenes(anterior.getListaImagenes());
        
        listaImagenes = anterior.getListaImagenes();
        
        actual.setPaciente(anterior.getPaciente());
        actual.setPlantilla(anterior.getPlantilla());
        actual.setPlantillaEstudioImagenes(anterior.getPlantillaEstudioImagenes());
        actual.setProfesional(anterior.getProfesional());
        actual.setProfesionalQueLoCompleto(anterior.getProfesionalQueLoCompleto());
        actual.setNombreArchivo(anterior.getNombreArchivo());
    }

    public EstudioImaginologia getEstudioImaginologia() {
        return estudioImaginologia;
    }

    public List<Imagen> getListaImagenes() {
        return listaImagenes;
    }

    public String getNombreEstudio() {
        return nombreEstudio;
    }

    public List<Gravedad> getListaGravedades() {
        return listaGravedades;
    }

    public boolean getBotonesActivados() {
        return botonesActivados;
    }

    public Imagen getImagenSeleccionada() {
        return imagenSeleccionada;
    }

    public void setImagenSeleccionada(Imagen imagenSeleccionada) {
        this.imagenSeleccionada = imagenSeleccionada;
    }

    @Override
    public void seCerroVentanaHija(String nombre) {
        BindUtils.postNotifyChange(null, null, this, "listaImagenes");
    }

}
